import { createAlova,  } from 'alova'
import adapterFetch from 'alova/fetch'
import customAdapterFetch from './custom-adapter-fetch'
import ReactHook from 'alova/react'
import { checkApiLimit } from '@/plugins/checkApiLimit'
import type { Method } from 'alova'

const alovaInstance = createAlova({
  // baseURL: import.meta.env.VITE_API_PROXY_PREFIX,
  timeout: 30000,
  statesHook: ReactHook,
  requestAdapter: customAdapterFetch(),
  // 动态调整baseURL（通过method的meta参数）
  beforeRequest: (_: Method) => {
  },
  responded: {
    // 请求成功的拦截器
    // 当使用 `alova/fetch` 请求适配器时，第一个参数接收Response对象
    // 第二个参数为当前请求的method实例，你可以用它同步请求前后的配置信息
    onSuccess: async (response, _) => {
      console.log('response', response)
      const status = response.status
      const clonedResponse = response.clone()
      if (response.status === 200 || response.status === 304) {
        try {
          return await response.json() as ResponseType
        } catch {
          return clonedResponse
        }
      } else if (status >= 400 && status < 600) {
        // 请求失败处理
        throw new Error(response.statusText)
      } else {
        throw new Error((await response.json()).message)
      }
    },
    // 请求失败的拦截器
    // 请求错误时将会进入该拦截器。
    // 第二个参数为当前请求的method实例，你可以用它同步请求前后的配置信息
    onError: (err, _) => {
      return err
    },
    // 请求完成的拦截器
    // 当你需要在请求不论是成功、失败、还是命中缓存都需要执行的逻辑时，可以在创建alova实例时指定全局的`onComplete`拦截器，例如关闭请求 loading 状态。
    // 接收当前请求的method实例
    onComplete: async _ => {
      // 处理请求完成逻辑
    }
  }
})

const delayLoadingMiddleware = (delay = 1000) => async (ctx: {
  proxyStates: {
    loading: {
      v: boolean
    }
  }
  controlLoading: () => void
}, next: () => Promise<unknown>) => {
  const { loading } = ctx.proxyStates
  ctx.controlLoading()
  const timer = setTimeout(() => {
    loading.v = true
  }, delay)
  await next()
  loading.v = false
  clearTimeout(timer)
}

const createAlovaMethod = (config: ApiRequestConfig): Method => {
  const {
    api: {
      url,
      method = 'POST',
      proxyPrefix,
      headers,
    },
    params,
    name,
    timeout = 30000,
    cacheFor,
    hitSource,
    transform,
    shareRequest,
    meta,
  } = config

  // 校验必填参数
  if (!url && !proxyPrefix) {
    throw new Error('api.url is required')
  }

  if (checkApiLimit(60 - 1, 1000 * 60 * 5)) {
    throw new Error('API请求次数超过限制')
  }

  console.log('ApiRequest: ', url, headers)

  return alovaInstance.Request({
    url: url,
    method: method,
    params: method.toLocaleUpperCase() === 'GET' ? params : undefined,
    data: method.toLocaleUpperCase() === 'POST' ? params : undefined,
    headers: headers || {},
    name,
    timeout,
    cacheFor,
    hitSource,
    transform,
    shareRequest,
    meta,
  })
}

const createCustomAlovaInstance = <ResultRecord>({
  beforeRequest,
  onSuccess,
  onError,
  onComplete
}: {
  beforeRequest?: (method: Method) => void,
  onSuccess?: (response: Response, method: Method) => Promise<ResultRecord>,
  onError?: (error: Error) => void | Promise<void>,
  onComplete?: () => void,
}): typeof alovaInstance => {
  return createAlova({
    // baseURL: import.meta.env.VITE_API_PROXY_PREFIX,
    timeout: 30000,
    statesHook: ReactHook,
    // requestAdapter: CustomRequestAdapter,
    requestAdapter: customAdapterFetch(),
    // 动态调整baseURL（通过method的meta参数）
    beforeRequest: beforeRequest,
    responded: {
      // 请求成功的拦截器
      // 当使用 `alova/fetch` 请求适配器时，第一个参数接收Response对象
      // 第二个参数为当前请求的method实例，你可以用它同步请求前后的配置信息
      onSuccess: onSuccess,
      // 请求失败的拦截器
      // 请求错误时将会进入该拦截器。
      // 第二个参数为当前请求的method实例，你可以用它同步请求前后的配置信息
      onError: onError,
      // 请求完成的拦截器
      // 当你需要在请求不论是成功、失败、还是命中缓存都需要执行的逻辑时，可以在创建alova实例时指定全局的`onComplete`拦截器，例如关闭请求 loading 状态。
      // 接收当前请求的method实例
      onComplete: onComplete
    }
  })
}
export {
  alovaInstance,
  delayLoadingMiddleware, // 延迟加载中间件
  createAlovaMethod,
  createCustomAlovaInstance, // 创建自定义alova实例
}